package com.youyun56.gps.sms;

import java.io.File;
import java.io.FileInputStream;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import com.j3.db.ConnectionManager;
import com.j3.db.DataSourceUnRegisterException;
import com.j3.sql.GridUtils;
import com.j3.sql.SqlFunc;

public class SmsSender implements Runnable {
    private final static Logger logger = Logger.getLogger(SmsSender.class);
    private Properties props = new Properties();
    private static Pattern pattern = Pattern.compile("^1[0-9]{10}?$");
    private ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

    public SmsSender() throws Exception {
        initDB();
    }

    protected void loadNewTask() throws SQLException {
        GridUtils grid = new GridUtils();
        grid.init("select id,mobiles,context,smsType from sms where done = 0 limit 1");
        if (grid.next()) {
            if (SmsType.TOCITYCARS.name().equals(grid.get("smsType"))) {
                sendToCityCars(grid);
            } else {
                normalSend(grid);
            }
        }

    }

    private void normalSend(GridUtils grid) throws DataSourceUnRegisterException, SQLException {
        Long id = grid.getLong("id");
        String[] mobiles = grid.get("mobiles").split(",");
        for (String mobile : mobiles) {
            Sms sms = new Sms();
            sms.setId(id);
            sms.setContext(grid.get("context"));
            if (pattern.matcher(mobile).matches()) {
                sms.setMobile(mobile);
                pool.submit(new SingleSmsSender(sms));
            } else {
                logger.error(String.format("%s is not a mobile in sms", mobile, id));
            }
        }
        SqlFunc fun = new SqlFunc();
        fun.executeUpdate(String.format("update sms set done = 1 where id = %d", id));
    }

    private void sendToCityCars(GridUtils grid) throws SQLException {
        Long city = grid.getLong("mobiles");
        String context = grid.get("context");
        Long id = grid.getLong("id");
        GridUtils carDao = new GridUtils();
        carDao.init(String.format("select DISTINCT(carMobile) from car where current_city = %d and status = 'VIP' and DATEDIFF(endDay,NOW()) > 0",
                city));
        while (carDao.next()) {
            Sms sms = new Sms();
            sms.setContext(context);
            String mobile = carDao.get("carMobile");
            if (pattern.matcher(mobile).matches()) {
                sms.setMobile(mobile);
                pool.submit(new SingleSmsSender(sms));
            } else {
                logger.error(String.format("%s is not a mobile in sms %d", mobile, id));
            }

        }
        SqlFunc fun = new SqlFunc();
        fun.executeUpdate(String.format("update sms set done = 1 where id = %d", id));
    }

    private void initDB() throws Exception {
        // TODO Auto-generated method stub
        props.load(new FileInputStream(PathConfig.ROOT + File.separator + "config.properties"));
        DataSource bds = BasicDataSourceFactory.createDataSource(props);
        ConnectionManager.registerDataSource("gps", bds);
        ConnectionManager.setDefaultDataSourceName("gps");
    }

    public void run() {
        // try {
        // loadNewTask();
        // } catch (SQLException e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        while (true) {
            try {
                loadNewTask();
                Thread.sleep(5000);
            }
            catch (Exception e) {
                // TODO Auto-generated catch block
                logger.error(e.getMessage(), e);
            }
        }
    }

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        System.setProperty("server", "sms");
        DOMConfigurator.configure(PathConfig.ROOT + "/log4j.xml");
        Thread thread = new Thread(new SmsSender());
        thread.start();
        thread.join();
        // thread
    }
}
